package com.apache.passport.common;

/**
 * JAVACC DEMO 1.0
 */

import com.apache.tools.ConfigUtil;
import com.apache.tools.StrUtil;
import org.apache.commons.io.IOUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * description:  白名单解析
 *
 * @author Hou Dayu 创建时间：2016-9-22
 */
public class XmlWhiteUtils {

    public static final String SUFFIX = "js,css,png,jpg,gif,bmp,swf,fla,ico";

    private static final String whiteFileName = "white.xml";

    private long lastUpateTime = 0l;//最后修改时间

    private static XmlWhiteUtils instance;

    private String filePath = "";

    private XmlWhiteUtils() {
        filePath = getClassLoaderPath() + "config/";
    }

    public static synchronized XmlWhiteUtils getInstance() {
        if (null == instance) {
            instance = new XmlWhiteUtils();
        }
        return instance;
    }

    public boolean deWhiteXml(Map<String, ArrayList<String>> whiteMap, String sysCode) {
        ArrayList<String> whiteUrlArrList = new ArrayList<String>(1);
        ArrayList<String> whiteParadigmArrList = new ArrayList<String>(1);
        String whiteUrlStr = "whiteUrl";
        String whiteListStr = "whiteList";
        String whiteParadigmStr = "whiteParadigm";
        boolean flag = true;
        InputStream stream = null;
        File oldfile = null;
        boolean flagMark = whiteMap.isEmpty();
        sysCode = StrUtil.isNotNull(sysCode) ? sysCode + "_" : "";
        String fileName = sysCode + whiteFileName;
        boolean cacheFlag = getConfigForCache("", fileName);
        if (cacheFlag) {
            Object obj = ConfigUtil.getInstance().getCache("").getCacheObjectByKey(fileName);
            String xmlStr = String.valueOf(obj);
            if (StrUtil.isNotNull(xmlStr)) {
                stream = IOUtils.toInputStream(xmlStr, Charset.forName("UTF-8"));
            }
        } else {
            if (filePath.indexOf(".jar") != -1) {
                stream = XmlWhiteUtils.class.getClassLoader()
                        .getResourceAsStream("config/" + whiteFileName);
                if (stream == null) {
                    if (flagMark) {
                        whiteMap.put(whiteUrlStr, whiteUrlArrList);
                        whiteMap.put(whiteParadigmStr, whiteParadigmArrList);
                    }
                    return false;
                }
            } else {
                oldfile = new File(filePath + whiteFileName);
                if (!oldfile.exists()) {
                    whiteMap.put(whiteUrlStr, whiteUrlArrList);
                    whiteMap.put(whiteParadigmStr, whiteParadigmArrList);
                    flag = false;
                    return flag;
                }
            }
        }
        if (oldfile != null && stream == null) {
            if (flagMark) {
                whiteMap.put(whiteUrlStr, whiteUrlArrList);
                whiteMap.put(whiteParadigmStr, whiteParadigmArrList);
            }
            return false;
        }
        try {
            SAXBuilder sb = new SAXBuilder();
            Document doc = null;
            if (oldfile != null) {
                doc = sb.build(oldfile);
            } else {
                doc = sb.build(stream);
            }
            Element root = doc.getRootElement();
            Element whiteList = root.getChild(whiteListStr);

            Element whiteUrl = whiteList.getChild(whiteUrlStr);
            List<?> whiteListUrlList = whiteUrl.getChildren();
            for (int i = 0; i < whiteListUrlList.size(); i++) {
                Element em = (Element) whiteListUrlList.get(i);
                whiteUrlArrList.add(em.getValue());
            }
            whiteMap.put(whiteUrl.getName(), whiteUrlArrList);

            Element whiteParadigm = whiteList.getChild(whiteParadigmStr);
            List<?> whiteParadigmList = whiteParadigm.getChildren();
            for (int i = 0; i < whiteParadigmList.size(); i++) {
                Element em = (Element) whiteParadigmList.get(i);
                whiteParadigmArrList.add(em.getValue());
            }
            whiteMap.put(whiteParadigm.getName(), whiteParadigmArrList);

        } catch (Exception e) {
            flag = false;
            if (flagMark) {
                whiteMap.put(whiteUrlStr, whiteUrlArrList);
                whiteMap.put(whiteParadigmStr, whiteParadigmArrList);
            }
        } finally {
            IOUtils.closeQuietly(stream);
        }
        return flag;
    }

    /**
     * @return 返回classes的绝对路径。
     */
    @SuppressWarnings("null")
    public String getClassLoaderPath() {
        String path = "";
        URL classLoaderUrl = Thread.currentThread().getContextClassLoader().getResource("");
        if (null == classLoaderUrl) {
            path = Thread.currentThread().getContextClassLoader().getResource("/")
                    .getPath();//tomcat/weblogic
        } else {
            path = classLoaderUrl.getPath();
        }
        if (!StrUtil.isNull(path)) {
            if (path.startsWith(File.separator) || path.startsWith("/")) {
                String systemType = getSystemType();
                if ("windows".equals(systemType))
                    path = path.substring(1);
            }
            if (!path.endsWith(File.separator) && !path.endsWith("/"))
                path += "/";
        }
        return path;
    }

    /**
     * 获取操作系统类型
     *
     * @return 返回操作系统类型
     */
    private String getSystemType() {
        String result = "windows";
        if (System.getProperty("os.name").equals("Linux")) {
            result = "linux";
        } else if ("Mac OS X".equals(System.getProperty("os.name"))) {
            result = "Mac OS X";
        }
        return result;
    }

    public boolean getConfigForCache(String cacheName, String key) {
        Object obj = ConfigUtil.getInstance().getCache(cacheName)
                .getCacheObjectByKey(key + "_flag");
        if (null == obj) {
            return false;
        } else {
            return true;
        }
    }
}
